/**
*      author: Y_Yao
*      created: 2024-10-15 17:08:23
**/

//#include<bits/stdc++.h>
#include<iostream>
using namespace std;
using LL = long long;
#define lc p<<1
#define rc p<<1|1
const LL LLINF = 1e18;
const int INF = 0x3f3f3f3f;
const int N = 1e5 + 7;
int s[4 * N];
int a[N];
int n;

struct node
{
    int l, r, val, lazy;
}tr[4 * N];

void pushup(int p)
{
    tr[p].val = tr[lc].val + tr[rc].val;
}

void build(int p, int l, int r)
{
    tr[p] = { l,r,a[l],0 };
    if (l == r)
    {
        return;
    }
    int mid = (l + r) >> 1;
    build(lc, l, mid);
    build(rc, mid + 1, r);
    pushup(p);
}

void pushdown(int p)
{
    if (tr[p].lazy)
    {
        tr[lc].val += tr[p].lazy * (tr[lc].r - tr[lc].l + 1);
        tr[rc].val += tr[p].lazy * (tr[rc].r - tr[rc].l + 1);
        tr[lc].lazy += tr[p].lazy;
        tr[rc].lazy += tr[p].lazy;
        tr[p].lazy = 0;
    }
}

void update(int p, int x, int y, int k)
{
    if (x <= tr[p].l && tr[p].r <= y)
    {
        tr[p].val += (tr[p].r - tr[p].l + 1) * k;
        tr[p].lazy += k;
        return;
    }

    int mid = (tr[p].l + tr[p].r) >> 1;
    pushdown(p);
    if (x <= mid) update(lc, x, y, k);
    if (y > mid) update(rc, x, y, k);
    pushup(p);
}

int query(int p, int x, int y)
{
    if (x <= tr[p].l && tr[p].r <= y)
    {
        return tr[p].val;
    }

    int mid = (tr[p].r + tr[p].l) >> 1;
    pushdown(p);
    int sum = 0;
    if (x <= mid) sum += query(lc, x, y);
    if (y > mid)sum += query(rc, x, y);
    return sum;
}

void solve()
{
    int oper,l, r;
    cin >> oper >> l >> r;


    if (oper == 1)
    {
        int k = 0;
        cin >> k;
        update(1, l, r, k);
    }
    else
    {
        int out = query(1, l, r);
        cout << out << endl;
    }
}

int main()
{
    ios::sync_with_stdio(false);
    cin.tie(0);

    int m;
    cin >> n >> m;
    for (int i = 1;i <= n;i++)
    {
        cin >> a[i];
    }
    build(1, 1, n);

    while (m--)
    {
        solve();
    }
    return 0;
}